package com.softserveinc.lahire.handlers;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import sun.awt.windows.WToolkit;

import com.softserveinc.lahire.builders.HTTPWorker;
import com.softserveinc.lahire.builders.Request;
import com.softserveinc.lahire.builders.ResponseDirector;
import com.softserveinc.lahire.builders.SimpleResponseBuilder;
import com.softserveinc.lahire.configurator.Configurator;
import com.softserveinc.lahire.server.Server;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Template;

/**
 * 
 * Class, that return admin_panel.cgi page. Admin panel allows administrator of
 * the server to: - Modify main parameters of the server - Start/Stop/Restart
 * server - Monitor current status of the server
 * 
 * @author Pavlo Lozovskiy
 */

public class AdminHandler implements Handler {

	private Handler parent = null;
	private Request request;

	public void setParent(Handler parent) {
		this.parent = parent;
	}

	public Handler getParent() {
		return parent;
	}

	public void handle(Request request) throws IOException {
		this.request = request;

		if (request.getUrl().equals("/admin_panel.cgi")
				| request.getUrl().equals("/submit.cgi")) {

			if (request.getUrl().equals("/admin_panel.cgi")) {

				if (authenticate(request.getParameters())) {

					sendPage(returnPage());

				} else {

					System.out.println("Not authorized");

					/*
					 * 303 Error setParent(new ErrorHandler); buffer =
					 * parent.handle(request);
					 */

				}
			} else if (request.getUrl().equals("/submit.cgi")) {

				if (Boolean.parseBoolean(request.getParameters()
						.get("modified"))) {

					for (Map.Entry<String, String> entry : request
							.getParameters().entrySet()) {

						if (!entry.getKey().equalsIgnoreCase("modidifed")) {
							Configurator.getInstance().getHashMap()
									.put(entry.getKey(), entry.getValue());
						}
					}
					sendPage(returnPage());

					System.out.println("Changes saved!");

					if (request.getParameters().get("action")
							.equalsIgnoreCase("reboot")) {

						Server.restartServer();
					}
				}
			}

			// return page

		} else {
			if (parent != null)
				parent.handle(request);
		}

	}

	private void sendPage(byte[] page) {

		request.setContentType(Configurator.mimeType.get("html"));

		HTTPWorker.responseDirector
				.setResponseBuilder(new SimpleResponseBuilder());
		
		String ip = request.getIpAddress();
		System.out.println("Entry created: " + ip + " " + SessionManager.getInstance().createSession(ip));

		HTTPWorker.responseDirector.constructResponse(page,
				request.getContentType(), HttpURLConnection.HTTP_OK, "sid="
						+ Math.abs(new Random().nextInt()));

	}

	private boolean authenticate(Map<String, String> credentials) {

		boolean passed = credentials.get("login").equalsIgnoreCase(
				Configurator.inner.get("login"))
				&& credentials.get("pass").equals(
						Configurator.inner.get("pass"));

		return passed;
	}

	private byte[] returnPage() throws IOException {

		ByteArrayOutputStream htmltemplate = new ByteArrayOutputStream();
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
				htmltemplate));

		Velocity.init();
		VelocityContext vc = new VelocityContext();

		fillupCart(vc, Configurator.getInstance().getHashMap());

		org.apache.velocity.Template t = Velocity.getTemplate("admin_panel.vm");
		t.merge(vc, writer);

		writer.flush();
		writer.close();

		return htmltemplate.toByteArray();
	}

	private void fillupCart(VelocityContext vc, HashMap<String, Object> map) {

		for (Map.Entry<String, Object> entry : map.entrySet()) {

			if (entry.getValue() instanceof HashMap<?, ?>) {
				fillupCart(vc, (HashMap<String, Object>) entry.getValue());
			} else {
				vc.put(entry.getKey(), entry.getValue());
			}
		}
	}

}
